/**
 *
 */
package com.suieqian.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suieqian.config.Env;
import com.suieqian.dao.UserDao;
import com.suieqian.dto.req.UserReq;
import com.suieqian.entity.User;
import com.suieqian.entity.UserRoleRef;
import com.suieqian.enums.DelStatusEnum;
import com.suieqian.exception.ServiceLogicException;
import com.suieqian.service.IUserRoleRefService;
import com.suieqian.service.IUserService;
import com.suieqian.util.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 *
 * @Description:
 * @author: tianhua.xie
 * @Date: 2017年2月9日 下午9:53:07 
 *
 */
@Service("userService")
@Transactional
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements IUserService {
    @Resource
    private UserDao userDao;

    @Resource
    private IUserRoleRefService userRoleRefService;

    @Override
    public void save(UserReq userReq) {
        if (Objects.isNull(userReq) || StrUtil.isBlank(userReq.getUserAccount())) {
            throw new ServiceLogicException("用户账号不能为空");
        }
        Integer userId = null;
        User dbUser = userDao.selectByAccount(userReq.getUserAccount());
        if (Objects.nonNull(dbUser)) {
            throw new ServiceLogicException("该用户账号【" + userReq.getUserAccount() + "】已存在");
        }
        if (null == dbUser && StrUtil.isNotBlank(userReq.getPhone())) {
            LambdaQueryWrapper<User> userLambdaQueryWrapper = Wrappers.lambdaQuery();
            userLambdaQueryWrapper.eq(User::getPhone, userReq.getPhone());
            userLambdaQueryWrapper.eq(User::getDelStatus, DelStatusEnum.NORMAL.getCode());
            dbUser = this.getOne(userLambdaQueryWrapper);
            if (Objects.nonNull(dbUser)) {
                throw new ServiceLogicException("该手机号已经被绑定");
            }
        }
        // 删除角色
        LambdaQueryWrapper<UserRoleRef> lqw = Wrappers.lambdaQuery();
        lqw.eq(UserRoleRef::getUserId, userReq.getUserId());
        userRoleRefService.remove(lqw);
        // 已存在
        if (Objects.nonNull(userReq.getUserId())) {
            User saveUser = BeanUtil.copyProperties(userReq, User.class);
            saveUser.setUserPwd(dbUser.getUserPwd())
                    .setCreatedTime(dbUser.getCreatedTime())
                    .setDelStatus(DelStatusEnum.NORMAL.getCode())
                    .setUpdateId(Env.getUser().getUpdateId())
                    .setUpdateName(Env.getUser().getUserAccount())
                    .setUpdateTime(LocalDateTime.now());
            userDao.updateById(saveUser);
            return;
        }

        User saveUser = BeanUtil.copyProperties(userReq, User.class);
        saveUser.setCreatedTime(LocalDateTime.now())
                .setDelStatus(DelStatusEnum.NORMAL.getCode())
                .setCreateId(Env.getUser().getUserId())
                .setUpdateId(Env.getUser().getUpdateId())
                .setUpdateName(Env.getUser().getUserAccount())
                .setUpdateTime(LocalDateTime.now());
        // 密码加密
        try {
            String userPwd = dbUser.getUserAccount() + dbUser.getPhone().substring(dbUser.getPhone().length() - 4, dbUser.getPhone().length());
            saveUser.setUserPwd(MD5Util.md5Encode(userPwd));
        } catch (Exception e) {
            throw new ServiceLogicException("系统错误");
        }
        // 保存角色
        if (CollUtil.isNotEmpty(userReq.getRoleIdList())) {
            List<UserRoleRef> userRoleRefList = userReq.getRoleIdList().stream().map(item -> {
                UserRoleRef userRoleRef = new UserRoleRef();
                userRoleRef.setRoleId(item).setUserId(userReq.getUserId());
                return userRoleRef;
            }).collect(Collectors.toList());
            userRoleRefService.saveBatch(userRoleRefList);
        }
        // 添加角色信息
        // 插入信息 并 获取主键值
        userDao.insert(saveUser);
    }

    @Override
    public void editUser(UserReq user) {
        if (Objects.isNull(user.getUserId())) {
            throw new ServiceLogicException("用户id不能为空");
        }
        if (StrUtil.isBlank(user.getUserAccount())) {
            throw new ServiceLogicException("用户账号不能为空");
        }
        User dbUser = userDao.selectByAccount(user.getUserAccount());
        if (Objects.isNull(dbUser)) {
            throw new ServiceLogicException("用户参数错误");
        }
        if (Objects.nonNull(dbUser) && !user.getUserAccount().equals(dbUser.getUserAccount())) {
            throw new ServiceLogicException("该用户账号【" + user.getUserAccount() + "】已存在");
        }
        if (StrUtil.isNotBlank(user.getPhone())) {
            LambdaQueryWrapper<User> userLambdaQueryWrapper = Wrappers.lambdaQuery();
            userLambdaQueryWrapper.eq(User::getPhone, user.getPhone());
            userLambdaQueryWrapper.eq(User::getDelStatus, DelStatusEnum.NORMAL.getCode());
            User phoneUser = this.getOne(userLambdaQueryWrapper);
            if (Objects.nonNull(phoneUser) && !phoneUser.getUserId().equals(user.getUserId())) {
                throw new ServiceLogicException("该手机号已经被绑定");
            }
        }
        // 删除角色
        LambdaQueryWrapper<UserRoleRef> lqw = Wrappers.lambdaQuery();
        lqw.eq(UserRoleRef::getUserId, user.getUserId());
        userRoleRefService.remove(lqw);

        // 保存角色
        if (CollUtil.isNotEmpty(user.getRoleIdList())) {
            List<UserRoleRef> userRoleRefList = user.getRoleIdList().stream().map(item -> {
                UserRoleRef userRoleRef = new UserRoleRef();
                userRoleRef.setRoleId(item).setUserId(user.getUserId());
                return userRoleRef;
            }).collect(Collectors.toList());
            userRoleRefService.saveBatch(userRoleRefList);
        }

        //保存用户
        User saveUser = BeanUtil.copyProperties(user, User.class);
        saveUser.setUserPwd(dbUser.getUserPwd())
                .setCreatedTime(dbUser.getCreatedTime())
                .setDelStatus(DelStatusEnum.NORMAL.getCode())
                .setUpdateId(Env.getUser().getUpdateId())
                .setUpdateName(Env.getUser().getUserAccount())
                .setUpdateTime(LocalDateTime.now());
        userDao.updateById(saveUser);
    }

    @Override
    public void deleteUser(Long delUserId) {
        if (Objects.isNull(delUserId)) {
            throw new ServiceLogicException("要删除的用户ID不能为空");
        }
        try {
            // 清除该用户在用户角色表的所有记录
//			userDao.deleteUserRolesByIds(decUserIds);
            User user = new User().setDelStatus(DelStatusEnum.ERROR.getCode())
                    .setUserId(delUserId)
                    .setUpdateId(Env.getUser().getUpdateId())
                    .setUpdateName(Env.getUser().getUserAccount())
                    .setUpdateTime(LocalDateTime.now());
            userDao.updateById(user);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceLogicException("系统错误", e);
        }
    }

    @Override
    public void modifyUserPwd(Long userId) {
        if (Objects.isNull(userId)) {
            throw new ServiceLogicException("用户ID不能为空");
        }
        User dbUser = userDao.selectById(userId);
        if (Objects.isNull(dbUser)) {
            throw new ServiceLogicException("该用户【" + userId + "】不存在");
        }
        String userPwd = dbUser.getUserAccount() + dbUser.getPhone().substring(dbUser.getPhone().length() - 4, dbUser.getPhone().length());
        log.info("{}重置密码{}", dbUser.getUserAccount(), userPwd);
        try {
            dbUser.setUserPwd(MD5Util.md5Encode(userPwd))
                    .setUpdateId(Env.getUser().getUpdateId())
                    .setUpdateName(Env.getUser().getUserAccount())
                    .setUpdateTime(LocalDateTime.now());
            userDao.updateById(dbUser);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceLogicException(e.getMessage());
        }

    }
}
